package db0

import (
	"log"
	model0 "searcher/src/model"
	"time"
)

type DbHifini struct {
	Id         uint   `gorm:"primarykey" json:"id"`   // 主键
	Title      string `json:"title" gorm:"index"`     //歌名
	MusicType  string `json:"musictype" gorm:"index"` //音乐类型
	FirstLink  string `json:"first"`                  //网盘链接1
	SecondLink string `json:"second"`                 //网盘链接2
	FirstCode  string `json:"code1"`                  //提取码1
	SecondCode string `json:"code2"`                  //提取码2
	Origin     string `json:"origin"`
	Created    string `json:"created"` // 日期时间(录入的时间)
	Updated    string `json:"updated"` // 日期时间(更新的时间)
	Click      uint   `json:"click"`   // 点击次数
	Valid      string `json:"valid"`   //是否有效(是不是死链)
	Saved      string `json:"saved"`   //是否保存
}

// init
func init() {
	db := Getdb()
	if err := db.AutoMigrate(&DbHifini{}); err != nil {
		println(err)
	}
}

type DbHifiniRef struct{}

// 类型转换
func convert(input model0.Hifini) (output DbHifini) {
	output.Title = input.Title
	output.MusicType = input.MusicType
	output.FirstLink = input.FirstLink
	output.FirstCode = input.FirstCode
	output.SecondLink = input.SecondLink
	output.SecondCode = input.SecondCode
	output.Origin = input.Origin
	output.Created = time.Now().Format("2006-01-02 15:04:05")
	return
}

// 类型转换
func batchConvert(input *[]model0.Hifini) *[]DbHifini {
	var batchOutput []DbHifini
	for _, item := range *input {
		batchOutput = append(batchOutput, convert(item))
	}
	return &batchOutput
}

// 实现接口
func (*DbHifiniRef) Save(entity model0.Hifini) {
	dbhifini := convert(entity)
	// fmt.Println(dbhifini)
	db := Getdb()

	// 这里有点坑, 必须传递引用 `&dbhifini`
	if err := db.Model(&DbHifini{}).Create(&dbhifini).Error; err != nil {
		log.Fatal(err)
	}
}

// 实现接口
func (*DbHifiniRef) BatchSave(entities *[]model0.Hifini) {
	target := batchConvert(entities)
	db := Getdb()
	// [db.Debug()] 将日志级别调整到info
	// 插入 `200` 条太多了?? -> 又是一个乌龙: `.Error` 忘记调用了
	// 这里的`target`已经是一个指针了
	// db.Debug()
	// 【注意】【重要】一定要记得`.Error` `&{0xc0002673f0 <nil> 30 0xc00026cf00 0}`
	if err := db.Model(&DbHifini{}).Create(target).Error; err != nil {
		log.Fatal(err) // `log.Fatal`会导致程序退出 os.Exit(1)
	}
}

// @Deprecated (已经废弃) 获取数据库表的记录数
func (*DbHifiniRef) Count() (_total int64) {
	db := Getdb()
	db.Model(&DbHifini{}).Count(&_total)
	return
}

// 获取`MusicType`
func (*DbHifiniRef) GetMusicType() *[]string {
	db := Getdb()

	var result []string

	// .Group("music_type")
	// .Distinct("music_type")
	db.Model(&DbHifini{}).Select("music_type").Distinct("music_type").Find(&result)

	return &result
}

// 根据歌名查询
func (*DbHifiniRef) QueryByTitle(page, pagesize uint, title string) *PageDatas[DbHifini] {
	db := Getdb()

	var offset = (page - 1) * pagesize
	var _total int64
	var result []DbHifini

	db.Model(&DbHifini{}).Where("title LIKE ?", "%"+title+"%").Count(&_total)
	db.Model(&DbHifini{}).Where("title LIKE ?", "%"+title+"%").
		Limit(int(pagesize)).Offset(int(offset)).Find(&result)

	res := PageDatas[DbHifini]{
		Total: _total,
		Datas: result,
	}

	return &res
}

// 根据`music type`查询
func (*DbHifiniRef) QueryByMtype(page, pagesize uint, mtype string) *PageDatas[DbHifini] {
	db := Getdb()

	var offset = (page - 1) * pagesize
	var _total int64
	var result []DbHifini

	db.Model(&DbHifini{}).Where("music_type = ?", mtype).Count(&_total)
	db.Model(&DbHifini{}).Where("music_type = ?", mtype).
		Limit(int(pagesize)).Offset(int(offset)).Find(&result)

	res := PageDatas[DbHifini]{
		Total: _total,
		Datas: result,
	}

	return &res
}

// 根据歌名和类型查询
func (*DbHifiniRef) QueryByTitleAndType(page, pagesize uint, title string,
	mtype string) *PageDatas[DbHifini] {

	db := Getdb()

	var offset = (page - 1) * pagesize
	var _total int64
	var result []DbHifini

	if mtype == "-1" && title == "" {
		// 查询所有数据
		db.Model(&DbHifini{}).Count(&_total)
		db.Model(&DbHifini{}).
			Limit(int(pagesize)).Offset(int(offset)).Find(&result)
	} else if mtype == "-1" {
		// 如果`mtype == "-1"`就是只查询`title`, `QueryByTitle`方法可以弃用了
		db.Model(&DbHifini{}).Where("title LIKE ?", "%"+title+"%").Count(&_total)
		db.Model(&DbHifini{}).Where("title LIKE ?", "%"+title+"%").
			Limit(int(pagesize)).Offset(int(offset)).Find(&result)
	} else if title == "" {
		// 如果`title==''`就只查询`mtype`
		db.Model(&DbHifini{}).Where("music_type = ?", mtype).Count(&_total)
		db.Model(&DbHifini{}).Where("music_type = ?", mtype).
			Limit(int(pagesize)).Offset(int(offset)).Find(&result)
	} else {
		db.Model(&DbHifini{}).Where("title LIKE ? AND music_type = ?", "%"+title+"%", mtype).Count(&_total)
		db.Model(&DbHifini{}).Where("title LIKE ? AND music_type = ?", "%"+title+"%", mtype).
			Limit(int(pagesize)).Offset(int(offset)).Find(&result)
	}

	res := PageDatas[DbHifini]{
		Total: _total,
		Datas: result,
	}

	return &res
}

// 为前端数据特意制造的结构体
type VueAutoInput struct {
	// { value: 'vue', link: 'https://github.com/vuejs/vue' },
	Value string `json:"value"`
}

// 类型转换
func convertToVueAutoInput(inputs *[]string) (outputs *[]VueAutoInput) {
	var res []VueAutoInput
	for _, item := range *inputs {
		var target VueAutoInput
		target.Value = item
		res = append(res, target)
	}
	outputs = &res
	return
}

// 模糊查询所有歌名
func (*DbHifiniRef) QueryAllTitles(title string) *PageDatas[VueAutoInput] {
	db := Getdb()

	var _total int64

	var result []string

	db.Model(&DbHifini{}).Where("title LIKE ?", title+"%").Count(&_total)
	db.Model(&DbHifini{}).Select("title").Where("title LIKE ?", title+"%").Find(&result)

	convertRes := convertToVueAutoInput(&result) // 类型转换

	res := PageDatas[VueAutoInput]{
		Total: _total,
		Datas: *convertRes,
	}

	return &res
}

// `click`代表前端的点击次数, `IncreaseClick`增加点击次数
func (*DbHifiniRef) IncreaseClick(id uint) {
	db := Getdb()
	if err := db.Exec(`UPDATE db_hifinis SET click = COALESCE(click, 0) + 1 WHERE id = ?`, id).Error; err != nil {
		log.Println(err)
	}
}
